home *** CD-ROM | disk | FTP | other *** search
/ ...taking it to the Macs! / ...taking it to the Macs!.iso / Extras / ActiveX Mac SDK / ActiveX SDK / Container Common / memstrm.cpp < prev    next >
Text File  |  1997-01-03  |  7KB  |  301 lines

  1. //
  2. //  MEMSTRM.CPP
  3. //
  4. //  Copyright (C) Microsoft Corporation, 1996
  5. //
  6. //  Implementation of a Netscape stream notification object that "writes" data
  7. //  to a memory buffer.  This memory buffer can be utilized externally with the
  8. //  IStream interface.
  9. //
  10. //  This has been broken up into CMemoryStreamNotify which does the simple
  11. //  copy-into-memory-buffer logic.  CMemoryOleStreamNotify implements an IStream
  12. //  interface on top of this class.
  13. //
  14.  
  15. #include "headers.h"
  16.  
  17. //
  18. //  CMemoryStreamNotify::~CMemoryStreamNotify
  19. //
  20.  
  21. CMemoryStreamNotify::~CMemoryStreamNotify()
  22. {
  23.     if (m_pStream != NULL)
  24.         CoTaskMemFree(m_pStream);
  25. }
  26.  
  27. //
  28. //  CMemoryStreamNotify::OnWrite
  29. //
  30.  
  31. int32
  32. CMemoryStreamNotify::OnWrite(NPStream *stream, int32 offset, int32 len, void
  33.     *buffer)
  34. {
  35. #pragma unused (stream, offset)
  36.     LPVOID pNewStream;
  37.     int32 BytesWritten;
  38.  
  39.     if (m_pStream == NULL) {
  40.         pNewStream = (LPVOID) CoTaskMemAlloc(len);
  41.     } else {
  42.         pNewStream = (LPVOID) CoTaskMemRealloc(m_pStream, m_StreamLength + len);
  43.     }
  44.  
  45.     if (pNewStream != NULL) {
  46.         BlockMove(buffer, ((LPBYTE) pNewStream + m_StreamLength), len);
  47.         m_pStream = pNewStream;
  48.         m_StreamLength += len;
  49.         BytesWritten = len;
  50.     } else {
  51.         //  Returning a negative value causes the stream to error out and be
  52.         //  destroyed.
  53.         BytesWritten = -1;
  54.     }
  55.  
  56.     return BytesWritten;
  57. }
  58.  
  59. //
  60. //  CMemoryOleStreamNotify::IUnknown::QueryInterface
  61. //
  62.  
  63. STDMETHODIMP
  64. CMemoryOleStreamNotify::QueryInterface(REFIID riid, LPVOID *ppvObj)
  65. {
  66.     HRESULT hr;
  67.     LPVOID pv;
  68.  
  69.     if (riid == IID_IUnknown || riid == IID_IStream) {
  70.         pv = (LPVOID)(LPSTREAM) this;
  71.         ++m_cRef;
  72.         hr = ResultFromScode(S_OK);
  73.     } else {
  74.         pv = NULL;
  75.         hr = ResultFromScode(E_NOINTERFACE);
  76.     }
  77.  
  78.     *ppvObj = pv;
  79.     return hr;
  80. }
  81.  
  82. //
  83. //  CMemoryOleStreamNotify::IUnknown::AddRef
  84. //
  85.  
  86. STDMETHODIMP_(ULONG)
  87. CMemoryOleStreamNotify::AddRef(void)
  88. {
  89.     return ++m_cRef;
  90. }
  91.  
  92. //
  93. //  CMemoryOleStreamNotify::IUnknown::Release
  94. //
  95.  
  96. STDMETHODIMP_(ULONG)
  97. CMemoryOleStreamNotify::Release(void)
  98. {
  99.     if (--m_cRef != 0)
  100.         return m_cRef;
  101.  
  102.     delete this;
  103.     return 0;
  104. }
  105.  
  106. //
  107. //  CMemoryOleStreamNotify::IStream::Read
  108. //
  109.  
  110. STDMETHODIMP
  111. CMemoryOleStreamNotify::Read(void *pv, DWORD cb, LPDWORD pcbRead)
  112. {
  113.     //  Verify that we're not try to read more bytes than are available.  If we
  114.     //  are, clip the actual number of bytes copied.  The OLE32 memory stream
  115.     //  implementation doesn't return an error, so we won't either.
  116.     if (((LONG) cb < 0) || (cb + (ULONG) m_SeekPosition > (ULONG) m_StreamLength)) {
  117.         if (m_fAsyncStreamInProgress) {
  118.             //  Special case: if we're in the middle of streaming some data from
  119.             //  the network, return E_PENDING so that async binding works
  120.             //  correctly.
  121.             //  BUGBUG:  Above if statement probably isn't adequate, review this.
  122.             return ResultFromScode(E_PENDING);
  123.         } else {
  124.             cb = m_StreamLength - m_SeekPosition;
  125.         }
  126.     }
  127.  
  128.     if (cb > 0) {
  129.         BlockMove((LPBYTE) m_pStream + m_SeekPosition, pv, cb);
  130.         m_SeekPosition += cb;
  131.     }
  132.  
  133.     if (pcbRead != NULL)
  134.         *pcbRead = cb;
  135.  
  136.     return ResultFromScode(S_OK);
  137. }
  138.  
  139. //
  140. //  CMemoryOleStreamNotify::IStream::Write
  141. //
  142.  
  143. STDMETHODIMP
  144. CMemoryOleStreamNotify::Write(void const *pv, DWORD cb, LPDWORD pcbWritten)
  145. {
  146. #pragma unused (pv, cb, pcbWritten)
  147.     return ResultFromScode(STG_E_ACCESSDENIED);
  148. }
  149.  
  150. //
  151. //  CMemoryOleStreamNotify::IStream::Seek
  152. //
  153.  
  154. STDMETHODIMP
  155. CMemoryOleStreamNotify::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin,
  156.     ULARGE_INTEGER *plibNewPosition)
  157. {
  158.     HRESULT hr = ResultFromScode(S_OK);
  159.     LONG lMove = (LONG) dlibMove.LowPart;
  160.  
  161.     //  Note that we don't care about dlibMove.HighPart.  Checking the Win32
  162.     //  OLE sources, there implementation of a memory stream doesn't bother, so
  163.     //  if the reference implementation blows off the issue of 64-bit, then we
  164.     //  sure as hell can.  In fact, the below was lifted from OLE.
  165.     switch (dwOrigin) {
  166.  
  167.         case STREAM_SEEK_SET:
  168.             if (lMove >= 0) {
  169.                 m_SeekPosition = lMove;
  170.             } else {
  171.                 hr = ResultFromScode(STG_E_SEEKERROR);
  172.             }
  173.             break;
  174.  
  175.         case STREAM_SEEK_CUR:
  176.             if (!(lMove < 0 && ((ULONG) -lMove) > (ULONG) m_SeekPosition)) {
  177.                 m_SeekPosition += lMove;
  178.             } else {
  179.                 hr = ResultFromScode(STG_E_SEEKERROR);
  180.             }
  181.             break;
  182.  
  183.         case STREAM_SEEK_END:
  184.             if (!(lMove < 0 && ((ULONG) -lMove) > (ULONG) m_StreamLength)) {
  185.                 m_SeekPosition += m_StreamLength + lMove;
  186.             } else {
  187.                 hr = ResultFromScode(STG_E_SEEKERROR);
  188.             }
  189.             break;
  190.  
  191.         default:
  192.             hr = ResultFromScode(STG_E_INVALIDFUNCTION);
  193.             break;
  194.     }
  195.  
  196.     if (plibNewPosition != NULL) {
  197.         plibNewPosition->HighPart = 0;
  198.         plibNewPosition->LowPart = m_SeekPosition;
  199.     }
  200.  
  201.     return hr;
  202. }
  203.  
  204. //
  205. //  CMemoryOleStreamNotify::IStream::SetSize
  206. //
  207.  
  208. STDMETHODIMP
  209. CMemoryOleStreamNotify::SetSize(ULARGE_INTEGER libNewSize)
  210. {
  211. #pragma unused (libNewSize)
  212.     //  We're a read-only stream, so there's no reason to resize our stream.
  213.     return ResultFromScode(STG_E_INVALIDFUNCTION);
  214. }
  215.  
  216. //
  217. //  CMemoryOleStreamNotify::IStream::CopyTo
  218. //
  219.  
  220. STDMETHODIMP
  221. CMemoryOleStreamNotify::CopyTo(LPSTREAM pstm, ULARGE_INTEGER cb, ULARGE_INTEGER
  222.     *pcbRead, ULARGE_INTEGER *pcbWritten)
  223. {
  224. #pragma unused (pstm, cb, pcbRead, pcbWritten)
  225.     //  There's no good reason for this not to be implemented.
  226.     return ResultFromScode(E_NOTIMPL);
  227. }
  228.  
  229. //
  230. //  CMemoryOleStreamNotify::IStream::Commit
  231. //
  232.  
  233. STDMETHODIMP
  234. CMemoryOleStreamNotify::Commit(DWORD grfCommitFlags)
  235. {
  236. #pragma unused (grfCommitFlags)
  237.     //  We can always "commit" because it's not possible to write to the stream.
  238.     return ResultFromScode(S_OK);
  239. }
  240.  
  241. //
  242. //  CMemoryOleStreamNotify::IStream::Revert
  243. //
  244.  
  245. STDMETHODIMP
  246. CMemoryOleStreamNotify::Revert(void)
  247. {
  248.     //  We can always "revert" because it's not possible to write to the stream.
  249.     return ResultFromScode(S_OK);
  250. }
  251.  
  252. //
  253. //  CMemoryOleStreamNotify::IStream::LockRegion
  254. //
  255.  
  256. STDMETHODIMP
  257. CMemoryOleStreamNotify::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb,
  258.     DWORD dwLockType)
  259. {
  260. #pragma unused (libOffset, cb, dwLockType)
  261.     return ResultFromScode(STG_E_INVALIDFUNCTION);
  262. }
  263.  
  264. //
  265. //  CMemoryOleStreamNotify::IStream::UnlockRegion
  266. //
  267.  
  268. STDMETHODIMP
  269. CMemoryOleStreamNotify::UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER
  270.     cb, DWORD dwLockType)
  271. {
  272. #pragma unused (libOffset, cb, dwLockType)
  273.     return ResultFromScode(STG_E_INVALIDFUNCTION);
  274. }
  275.  
  276. //
  277. //  CMemoryOleStreamNotify::IStream::Stat
  278. //
  279.  
  280. STDMETHODIMP
  281. CMemoryOleStreamNotify::Stat(STATSTG *pstatstg, DWORD grfStatFlag)
  282. {
  283. #pragma unused (grfStatFlag)
  284.     //  Implementation lifted from OLE32's memory stream.
  285.     memset(pstatstg, 0, sizeof(*pstatstg));
  286.     pstatstg->type = STGTY_STREAM;
  287.     pstatstg->cbSize.LowPart = m_StreamLength;
  288.     return ResultFromScode(S_OK);
  289. }
  290.  
  291. //
  292. //  CMemoryOleStreamNotify::IStream::Clone
  293. //
  294.  
  295. STDMETHODIMP
  296. CMemoryOleStreamNotify::Clone(LPSTREAM *ppstm)
  297. {
  298.     *ppstm = NULL;
  299.     return ResultFromScode(E_NOTIMPL);
  300. }
  301.